﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Elsa.Expressions.Contracts;
using Elsa.Extensions;
using Elsa.JavaScript.Models;
using Elsa.Workflows;
using Elsa.Workflows.Memory;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
using FastEndpoints;
using T.FAS.Runtime.MF.Activities.Extensions;
using T.FAS.Runtime.MF.Entity;
using T.FAS.Runtime.MF.SPI;
using T.ServiceComponent.DAC.Repository;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace T.FAS.Runtime.MF.Activities
{
    public class ConditionBranchActivity : FASActivity
    {

        IList<BranchCondition> _Conditions = new List<BranchCondition>();
        public List<string> Outcomes { get; set; }
        // 分支条件配置
        [Elsa.Workflows.Attributes.Input(
            Description = "The cases to evaluate.",
            UIHint = "switch-editor"
        )]
        public IList<BranchCondition> Conditions
        {
            get
            {
                return _Conditions;
            }
            set
            {
                _Conditions = value;
                Outcomes = value.Select(t => t.Label).ToList();
                Outcomes.Add(DefaultOutcome);
            }
        }

        /// <summary>
        /// 用于返回节点的入参使用
        /// </summary>
        public Dictionary<string, List<ConditionDetail>> ConditionDetails { get; set; }

        [Elsa.Workflows.Attributes.Input(Description = "A list of possible outcomes.", UIHint = InputUIHints.OutcomePicker)]
        public Input<ICollection<string>> PossibleOutcomes { get; set; } = null!;

     

        public ConditionBranchActivity()
        {
        }

        public string DefaultOutcome { get; set; } = "ELSE";

        protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
        {
            var expressionEvaluator = context.GetRequiredService<IExpressionEvaluator>();
            var matchCondition = false;
            var variables = context.GetVariableValues();
           var outputInstanceValues = new Dictionary<string, object>();
           var inputInstanceValues = new Dictionary<string, object>();

            try
            {
                foreach (var condition in Conditions)
                {
                    if (condition.Condition != null)
                    {
                        var result = await expressionEvaluator.EvaluateAsync<bool?>(condition.Condition, context.ExpressionExecutionContext);
                        await SetInputInstanceValue(context, condition);

                        if (result == true)
                        {
                            await context.CompleteActivityWithOutcomesAsync(new[] { condition.Label });
                            outputInstanceValues["result"] = true;
                            outputInstanceValues["selected_case_id"] = condition.Label;
                            matchCondition = true;
                            break;
                        }
                    }
                }
                if (matchCondition == false)
                {
                    // 所有条件都不满足时走默认分支
                    await context.CompleteActivityWithOutcomesAsync(new[] { DefaultOutcome });
                    outputInstanceValues["result"] = false;
                    outputInstanceValues["selected_case_id"] = null;
                }
                this.OutputInstanceValues[context.Id] = outputInstanceValues;
            }
            catch (Exception ex)
            {
                await context.FaultAndComplete(ex, this);
            }
           
        }

        private async Task SetInputInstanceValue(ActivityExecutionContext context,BranchCondition condition)
        {
            if (!ConditionDetails.ContainsKey(condition.Label)) return;
            var expressionEvaluator = context.GetRequiredService<IExpressionEvaluator>();

            var conditionDetails = ConditionDetails[condition.Label];
         var inputInstanceValues =new Dictionary<string, object>();

            foreach (var item in conditionDetails)
            {
                var actualValue = await expressionEvaluator.EvaluateAsync<object?>(JavaScriptExpression.Create(item.ActualValueExpression) , context.ExpressionExecutionContext);
                var expectedValue = item.ExpectedValue;
                if (expectedValue == null)
                {
                    expectedValue = await expressionEvaluator.EvaluateAsync<object?>(JavaScriptExpression.Create(item.ExpectedValueExpression), context.ExpressionExecutionContext);
                }
                item.ExpectedValue = expectedValue;
                item.ActualValue = actualValue;
                item.ExpectedValueExpression = null;
                item.ActualValueExpression = null;
            }

            inputInstanceValues["conditions"] = conditionDetails;
            this.InputInstanceValues[context.Id] = inputInstanceValues;
        }
    }
}
